﻿using CSTK.Core.TopShelf_Quartz.Common;
using CSTK.Core.TopShelf_Quartz.Job;
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CSTK.Core.TopShelf_Quartz.Base
{
   public class Base_Quartz
    {
        #region 公共变量
        /// <summary>
        /// 任务调度器
        /// </summary>
        public readonly IScheduler Scheduler;
        #endregion

        public Base_Quartz()
        {
            var properties = new NameValueCollection();
            // 设置线程池
            properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
            //设置线程池的最大线程数量
            properties["quartz.threadPool.threadCount"] = "5";
            //设置作业中每个线程的优先级
            properties["quartz.threadPool.threadPriority"] = ThreadPriority.Normal.ToString();
            //创建一个工厂
            var schedulerFactory = new StdSchedulerFactory(properties);
            //启动
            Scheduler = schedulerFactory.GetScheduler().Result;
            //1、开启调度
            Start();
            RunJobs();
        }

        #region MyRegion

        /// <summary>
        /// 开启任务
        /// </summary>
        public void Start()
        {
            Scheduler.Start();
            Console.WriteLine("Quarz服务已启动...");
        }
        /// <summary>
        /// 关闭任务
        /// </summary>
        public void Stop()
        {
            //true：表示该Sheduler关闭之前需要等现在所有正在运行的工作完成才能关闭
            //false：表示直接关闭
            Scheduler.Shutdown(true);
            Console.WriteLine("Quarz服务已停止...");
        }
        /// <summary>
        /// 暂停调度
        /// </summary>
        public void Pause()
        {
            Scheduler.PauseAll();
            Console.WriteLine("Quarz暂停调度.");
        }

        /// <summary>
        /// 继续调度
        /// </summary>
        public void Continue()
        {
            Scheduler.ResumeAll();
            Console.WriteLine("Quarz继续调度.");
        }
        #endregion

        #region 不同时间方式执行任务
        /// <summary>
        /// 时间间隔执行任务
        /// </summary>
        /// <typeparam name="T">任务类，必须实现IJob接口</typeparam>
        /// <param name="seconds">时间间隔(单位：秒)</param>
        public async Task<bool> ExecuteByInterval<T>(int seconds) where T : IJob
        {
            //2、创建工作任务
            IJobDetail job = JobBuilder.Create<T>().Build();

            //3、创建触发器
            ITrigger trigger = TriggerBuilder.Create()
           .StartNow()
           .WithSimpleSchedule(
                x => x.WithIntervalInSeconds(seconds)
                //x.WithIntervalInMinutes(1)
                .RepeatForever())
           .Build();

            //4、将任务加入到任务池
            await Scheduler.ScheduleJob(job, trigger);
            return true;
        }/// <summary>
         /// 指定时间执行任务
         /// </summary>
         /// <typeparam name="T">任务类，必须实现IJob接口</typeparam>
         /// <param name="cronExpression">cron表达式，即指定时间点的表达式</param>
        public async Task<bool> ExecuteByCron<T>(string cronExpression) where T : IJob
        {
            var sugarConnection = ConfigHelper.AppSettings("sugar");
            var ip = ConfigHelper.GetHostIP();
            if (string.IsNullOrEmpty(sugarConnection))
            {
                Console.WriteLine(ip, "请配置sugar连接字符串");
                return false;
            }

            //2、创建工作任务
            IJobDetail job = JobBuilder.Create<T>()
                 .UsingJobData("sqlconnection", sugarConnection)
                .UsingJobData("ip", ip)
                .Build();
            //3、创建触发器
            ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
            .StartNow()
            .WithCronSchedule(cronExpression)
            .Build();
            //4、将任务加入到任务池
            await Scheduler.ScheduleJob(job, trigger);
            return true;
        }
        #endregion

        #region 添加任务和触发器

        public void ExecuteJob<T>(string corn) where T : IJob
        {
            //var corn = ConfigHelper.AppSettings(strKey);
            ExecuteByCron<T>(corn).Wait();
        }
        #endregion
        private void RunJobs()
        {
            ScheduleJob<ServiceXFDXReaderSynJob>("XFDXReaderSynCorn");
        }

        private void ScheduleJob<T>(string configKey) where T : IJob
        {
            var cron = ConfigHelper.AppSettings(configKey);
            if (!string.IsNullOrEmpty(cron))
            {
                ExecuteJob<T>(cron);
            }
        }

    }
}
